Add CI job priority system#2217
Conversation
…ties # Conflicts: # .github/workflows/collectivex-sweep.yml
# Conflicts: # .github/workflows/collectivex-sweep.yml # .github/workflows/e2e-tests.yml # utils/changelog_gate_tests/test_run_sweep_gating.py
|
Claude finished @adibarra's task in 13m 28s —— View job Review of PR #2217 — CI job priority system
Findings1 blocking, 1 warning — posted as inline comments:
Checked and found sound
Notes (non-blocking)
中文:审查发现 1 个阻塞问题( |
There was a problem hiding this comment.
Beyond the two inline findings, I also checked whether the setup job's PR-controlled invocation of ci_priority.py lets a PR game its own CI priority score — it doesn't: the score is computed strictly from the job's own matrix fields (framework/precision/spec-decoding/etc., which already determine what actually runs) intersected with repo-owned weights in configs/ci-priority.yaml, and there is no ci-priority:pN override, so a PR can't inflate its priority beyond what its own changelog entry already implies.
Extended reasoning...
Ruled out a candidate self-scoring/gaming concern raised by a finder agent for the setup job in run-sweep.yml: ci_priority.py's inputs (matrix config fields, Fable criteria, GH-event labels) are either derived from the job's real configuration or from trusted sources, and there's no arbitrary-override path (no ci-priority:pN support), so a PR cannot inflate its own priority beyond what its declared job configuration legitimately implies.
Priority-aware CI scheduling
GitHub Actions does not natively prioritize self-hosted jobs. This PR adds an opt-in controller that decides which queued GPU job each compatible idle runner may accept.
How dispatch works
With priority scheduling enabled, a job requests labels similar to:
self-hostedb200ci-job-6.000-a81f23...Runners permanently carry only their normal hardware and identity labels. They do not permanently carry
ci-job-*labels.The controller:
ci-job-<score>-<hash>label.ci-job-*label.The combined label transports both the human-readable score and a unique 128-bit job hash through GitHub's queued-job API. Because every label must match, the hash prevents GitHub from selecting another job with the same hardware and priority.
Running jobs are never preempted or relabeled.
Single-node and multinode awareness
Existing runner labels remain compatibility constraints:
b200b200-multinodeA single-node runner cannot accept a multinode job unless it already satisfies the multinode label. The controller schedules the coordinating GitHub runner; existing Slurm launchers continue provisioning worker nodes.
Automatic scoring
All ordinary priorities are numeric, nonnegative, automatic, and uncapped. Higher scores run first.
For priority-enabled sweep runs, the priority classifier inspects the relevant change range and returns only verified priority facts, such as topology, workload type, precision, speculative decoding, framework, model family, checklist completion, and patchwork. For pushes it compares the preceding commit to the pushed tip; checklist completion remains PR-only.
Fable never receives weights and never calculates a score.
ci_priority.py:configs/ci-priority.yaml.ci-job-<score>-<hash>label metadata.This intersection keeps mixed matrices correct: a PR may contain both vLLM and SGLang jobs, but each job receives only its matching criteria. Main-branch pushes receive the same deterministic matrix-field scoring plus diff-derived classifier criteria.
Malformed or unavailable Fable output conservatively classifies the PR as patchwork. Arbitrary
ci-priority:pNoverrides are not supported.Ties are resolved by queue timestamp and job ID. Runner selection preserves scarce exact-match runners when a less-constrained runner can accept the higher-priority job.
Job hashes
Generated job hashes are the first 128 bits of a SHA-256 digest over:
Manual matrix workflows derive the same 32-character hash from their run and matrix-cell identity. Hashes are routing identifiers, not credentials or secrets.
A score alone could release any compatible job with that priority.
ci-job-<score>-<hash>combines ordering and one-job identity in a single exact-match label.Protected
skip_queueskip_queueis the only absolute bypass mechanism. The workflow keeps the job's ordinary numeric priority and adds a PR-scoped skip request label.The trusted controller then:
SemiAnalysisAI/Coremembership.Unauthorized or unverifiable requests retain their numeric priority. The scheduler credential remains inside the trusted controller and is never passed to PR-controlled workflow code.
Required controller-token permissions:
Safety and failure behavior
Activation requires deploying the controller and setting:
PRIORITY_SCHEDULER_ENABLED=trueVerification
actionlint.skip_queueoutranked numeric priority100.000while retaining its numeric job label.